package com.seh.contentcenter.service.Impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seh.contentcenter.dto.PostDTO;
import com.seh.contentcenter.dto.UserDTO;
import com.seh.contentcenter.entity.Post;
import com.seh.contentcenter.feignclient.UserCenterFeignClient;
import com.seh.contentcenter.mapper.PostMapper;
import com.seh.contentcenter.service.PostService;
import com.seh.contentcenter.utils.DTOUtil;
import com.seh.contentcenter.utils.UserUtil;
import com.seh.contentcenter.utils.WrapperUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


@Service
public class PostServiceImpl implements PostService {
    @Autowired
    private PostMapper postMapper;

    @Autowired
    private CommentServiceImpl commentService;

    @Autowired
    private ReplyServiceImpl replyService;

    @Autowired
    private RedisTemplate<String, Object> objectRedisTemplate;

    @Autowired
    private UserCenterFeignClient userCenterFeignClient;

    private static Integer userPageSize = 3;

    private static int pageSize = 6;//广场分页，一页的数量

    /**
     * 新建帖子
     * @param post
     * @return
     */
    @Override
    public String addPost(Post post) {
        int insert = postMapper.insert(post);
        if (insert > 0) {
            // 删除对应的缓存条目
            objectRedisTemplate.delete("post");
            objectRedisTemplate.delete("userPosts");
            return "新建成功";
        }
        return "新建失败";
    }

    /**
     * 查询所有帖子
     *
     * @return
     */
    @Cacheable(value = "post", key = "#pageIndex")
    @Override
    public List<PostDTO> getPostList(Integer pageIndex) {
        if (pageIndex <= 0) {
            throw new IllegalArgumentException("pageIndex should be greater than 0.");
        }
        //判断缓存中是否存在数据
        Boolean hasKey = objectRedisTemplate.opsForHash().hasKey("post", pageIndex.toString());
        List<PostDTO> recordsDTO = new ArrayList<>();
        if (hasKey) {
            //从缓存中获取数据
            List<Post> records = JSONObject.parseArray(objectRedisTemplate.opsForHash().get("post", pageIndex.toString()).toString(), Post.class);

            records.forEach(f -> {
                PostDTO postDTO = DTOUtil.convertPost(f);
                UserDTO userDTO = UserUtil.getUserDTOFromCache(f.getAuthorId(), objectRedisTemplate, userCenterFeignClient);
                postDTO.setUserDTO(userDTO);
                postDTO.setReplyCount(replyCounts(f));
                recordsDTO.add(postDTO);
            });
        } else {
            Page<Post> page = new Page<>(pageIndex, pageSize);
            QueryWrapper<Post> queryWrapper = new QueryWrapper<Post>().orderByDesc("create_time");
            page = postMapper.selectPage(page, queryWrapper);
            List<Post> records = page.getRecords();

            records.forEach(f -> {
                PostDTO postDTO = DTOUtil.convertPost(f);
                UserDTO userDTO = userCenterFeignClient.findUserInfoById(f.getAuthorId());
                postDTO.setUserDTO(userDTO);
                postDTO.setReplyCount(replyCounts(f));
                recordsDTO.add(postDTO);
            });
            //将数据库查询到的结果存入缓存中
            objectRedisTemplate.opsForHash().put("post", pageIndex.toString(), JSONUtil.toJsonStr(records));
        }

        return recordsDTO;
    }

    /**
     * 根据用户id，查询此用户所用的发帖信息
     * @param id
     * @param pageIndex
     * @return
     */
    @Cacheable(value = "userPosts", key = "#id + '-' + #pageIndex")
    @Override
    public List<PostDTO> getPostByUserId(Integer id, Integer pageIndex) {
        // 构建缓存键，使用用户ID和页面索引作为键
        String cacheKey = id + "-" + pageIndex;

        // 检查缓存中是否存在数据
        Boolean hasKey = objectRedisTemplate.opsForHash().hasKey("userPosts", cacheKey);
        List<PostDTO> postDTOList = new ArrayList<>();

        if (hasKey) {
            // 从缓存中获取数据
            List<Post> postList = JSONObject.parseArray(objectRedisTemplate.opsForHash().get("userPosts", cacheKey).toString(), Post.class);

            postList.forEach(f -> {
                PostDTO postDTO = DTOUtil.convertPost(f);
                postDTO.setReplyCount(replyCounts(f));
                postDTOList.add(postDTO);
            });
        } else {
            Page<Post> page = new Page<>(pageIndex, userPageSize);
            QueryWrapper<Post> queryWrapper = WrapperUtil.pageWrapper(id, "create_time", "author_id");
            page = postMapper.selectPage(page, queryWrapper);
            List<Post> postList = page.getRecords();

            postList.forEach(f -> {
                PostDTO postDTO = DTOUtil.convertPost(f);
                postDTO.setReplyCount(replyCounts(f));
                postDTOList.add(postDTO);
            });

            // 将查询到的结果存入缓存中
            objectRedisTemplate.opsForHash().put("userPosts", cacheKey, JSONUtil.toJsonStr(postList));
        }

        return postDTOList;
    }

    /**
     * 通过主键id，查询帖子的详细信息
     * @param id
     * @return
     */
    @Cacheable(value = "postDetails", key = "#id")
    @Override
    public PostDTO selectPostById(Integer id) {
        // 检查缓存中是否存在数据
        Boolean hasKey = objectRedisTemplate.opsForHash().hasKey("postDetails", id.toString());

        if (hasKey) {
            // 从缓存中获取数据
            Post post = JSONObject.parseObject(objectRedisTemplate.opsForHash().get("postDetails", id.toString()).toString(), Post.class);
            PostDTO postDTO = DTOUtil.convertPost(post);
            postDTO.setUserDTO(userCenterFeignClient.findUserInfoById(post.getAuthorId()));
            return postDTO;
        } else {
            // 从数据库中查询帖子信息
            Post post = postMapper.selectById(id);
            PostDTO postDTO = DTOUtil.convertPost(post);
            postDTO.setUserDTO(userCenterFeignClient.findUserInfoById(post.getAuthorId()));

            // 将查询到的结果存入缓存中
            objectRedisTemplate.opsForHash().put("postDetails", id.toString(), JSONUtil.toJsonStr(post));
            return postDTO;
        }
    }

    /**
     * 根据帖子ID 逻辑删除帖子
     * @param postId
     * @return
     */
    @Override
    public String deletePostById(Integer postId) {
        int i = postMapper.deleteById(postId);
        if (i == 1) {
            // 删除成功，更新Redis缓存
            objectRedisTemplate.delete("post");
            return "删除成功";
        }
        return "删除失败";
    }


    /**
     * 计算一个帖子的所有回复数
     * @param post
     * @return
     */
    public Integer replyCounts(Post post) {
        Integer nums = commentService.commentNums(post.getPostId()) +
                replyService.replyNums(commentService.findAllFid(post.getPostId()));
        return nums;
    }

}
